package com.central.apps.handler.timeTask.project;

import com.central.app.common.quartz.QuartzJob;
import com.central.app.common.util.DateUtils;
import com.central.app.service.HandlerService;
import com.central.apps.entity.BlMessage;
import com.central.apps.service.MessageService;
import com.central.bizcommon.model.schedule.JobParams;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
//禁止并发执行(Quartz不要并发地执行同一个job定义（这里指一个job类的多个实例）)
@DisallowConcurrentExecution
public class BudgetWarnTask extends QuartzJob {
    @Autowired
    private HandlerService handlerService;
    @Autowired
    private MessageService messageService;

    /**
     * 任务
     *
     * @param context
     * @param jobnum
     * @param jobname
     * @param jobparams
     */
    @SneakyThrows
    @Override
    public void executeJob(JobExecutionContext context, String jobnum, String jobname, List<JobParams> jobparams) {
        // 查询项目预算预警配置信息
        List<Map<String, Object>> cfgList = handlerService.findBySql("select * from gq_pbwarncfg where status = '可用'");

        if (CollectionUtils.isEmpty(cfgList)) {
            return;
        }

        for (Map<String, Object> cfgMap : cfgList) {
            Integer id = MapUtils.getInteger(cfgMap, "id");
            String warnCategory = MapUtils.getString(cfgMap, "warncategory");
            String warnType = MapUtils.getString(cfgMap, "warntype");

            List<Map<String, Object>> cfgDtlList = handlerService.findBySql("select calculatefrom, daysfrom, calculateto, daysto, executeratio, msgformat from gq_pbwarncfgdtl where pbwcid = " + id);
            if (CollectionUtils.isEmpty(cfgDtlList)) {
                continue;
            }

            for (Map<String, Object> cfgDtlMap : cfgDtlList) {
                Integer daysFrom = MapUtils.getInteger(cfgDtlMap, "daysfrom");
                Integer daysTo = MapUtils.getInteger(cfgDtlMap, "daysto");
                Integer executeRatio = MapUtils.getInteger(cfgDtlMap, "executeratio");

                switch (warnCategory) {
                    case "概算":
                        List<Map<String, Object>> proList = null;
                        String fieldName = "";
                        String costExeStatus = "";

                        switch (warnType) {
                            case "高于":
                                fieldName = "executedays";
                                // 查询项目信息
                                proList = handlerService.findBySql("select id, subjectno, executedays, unexecutedays, bexecuteratio, proleader, personincharge from gq_proaccount where " + fieldName + " between " + daysFrom + " and " + daysTo + " and bexecuteratio > " + executeRatio);
                                costExeStatus = "执行偏快";
                                break;
                            default:
                                fieldName = "unexecutedays";
                                // 查询项目信息
                                proList = handlerService.findBySql("select id, subjectno, executedays, unexecutedays, bexecuteratio, proleader, personincharge from gq_proaccount where " + fieldName + " between " + daysFrom + " and " + daysTo + " and bexecuteratio < " + executeRatio);
                                costExeStatus = "执行偏慢";
                                break;
                        }

                        if (CollectionUtils.isNotEmpty(proList)) {
                            for (Map<String, Object> proMap : proList) {
                                Integer proId = MapUtils.getInteger(proMap, "id");// id
                                Integer proLeader = MapUtils.getInteger(proMap, "proleader");// 项目主管
                                Integer personInCharge = MapUtils.getInteger(proMap, "personincharge");// 项目负责人
                                String subjectNo = MapUtils.getString(proMap, "subjectno");
                                String executeDays = MapUtils.getString(proMap, "executedays");
                                String unExecuteDays = MapUtils.getString(proMap, "unexecutedays");
                                String bexecuteRatio = MapUtils.getString(proMap, "bexecuteratio");

                                // 更新项目成本执行状态数据
                                handlerService.updateBySql("update gq_proaccount set costexestatus = '" + costExeStatus + "' where id = " + proId);

                                // 通知项目主管
                                BlMessage message = new BlMessage();
                                message.setTitle("项目概算预警");

                                switch (warnType) {
                                    case "高于":
                                        message.setContent("课题号<b>" + subjectNo + "</b>预算执行偏快, 执行天数: <b>" + executeDays + "</b>, 成本执行比例: <b>" + bexecuteRatio + "</b>");
                                        break;
                                    default:
                                        message.setContent("课题号<b>" + subjectNo + "</b>预算执行偏慢, 未执行天数: <b>" + unExecuteDays + "</b>, 成本执行比例: <b>" + bexecuteRatio + "</b>");
                                        break;
                                }

                                message.setIsshow("未读");
                                message.setCreateuser("0");
                                message.setCreateuserdesc("系统");

                                // 通知项目主管
                                sendMessage(message, proLeader);
                                // 通知项目负责人
                                sendMessage(message, personInCharge);
                            }
                        }

                        break;
                    default:
                        List<Map<String, Object>> proPlanList = null;
                        int year = DateUtils.getCurrentYear();
                        Date currentDate = DateUtils.getCurrentDate();
                        Date yearStartDate = DateUtils.strToDate(year + "-01-01", "yyyy-MM-dd");
                        Date yearEndDate = DateUtils.strToDate(year + "-12-31", "yyyy-MM-dd");
                        long executeDays = DateUtils.daysBetweenExpWeekEnd(yearStartDate, currentDate);
                        long unExecuteDays = DateUtils.daysBetweenExpWeekEnd(currentDate, yearEndDate);
                        switch (warnType) {
                            case "高于":
                                // 查询项目实施策划信息
                                proPlanList = handlerService.findBySql("select id, subjectno, bexecuteratio, proleader, personincharge from gq_proplan where year = '" + year + "' and bexecuteratio > " + executeRatio);
                                break;
                            default:
                                // 查询项目实施策划信息
                                proPlanList = handlerService.findBySql("select id, subjectno, bexecuteratio, proleader, personincharge from gq_proplan where year = '" + year + "' and bexecuteratio < " + executeRatio);
                                break;
                        }

                        if (CollectionUtils.isNotEmpty(proPlanList)) {
                            for (Map<String, Object> proPlanMap : proPlanList) {
                                Integer proLeader = MapUtils.getInteger(proPlanMap, "proleader");// 项目主管
                                Integer personInCharge = MapUtils.getInteger(proPlanMap, "personincharge");// 项目负责人
                                String subjectNo = MapUtils.getString(proPlanMap, "subjectno");
                                String bexecuteRatio = MapUtils.getString(proPlanMap, "bexecuteratio");

                                // 通知项目主管
                                BlMessage message = new BlMessage();
                                message.setTitle("项目年度预算预警");

                                switch (warnType) {
                                    case "高于":
                                        message.setContent("课题号<b>" + subjectNo + "</b>" + year + "年预算执行偏快, 执行天数: <b>" + executeDays + "</b>, 成本执行比例: <b>" + bexecuteRatio + "</b>");
                                        break;
                                    default:
                                        message.setContent("课题号<b>" + subjectNo + "</b>" + year + "预算执行偏慢, 未执行天数: <b>" + unExecuteDays + "</b>, 成本执行比例: <b>" + bexecuteRatio + "</b>");
                                        break;
                                }

                                message.setIsshow("未读");
                                message.setCreateuser("0");
                                message.setCreateuserdesc("系统");

                                // 通知项目主管
                                sendMessage(message, proLeader);
                                // 通知项目负责人
                                sendMessage(message, personInCharge);
                            }
                        }

                        break;
                }
            }
        }
    }

    /**
     * 发送消息
     *
     * @param message
     * @param personId
     */
    private void sendMessage(BlMessage message, Integer personId) throws Exception {
        if (personId != null) {
            // 查询人员对应系统用户信息
            String userId = "";
            String userName = "";
            Map<String, Object> userMap = handlerService.findOneBySql("select a.id, a.nickname from sys_user a inner join gq_person t on t.id = a.field10 where t.id = " + personId);
            if (userMap != null && !userMap.isEmpty()) {
                userId = MapUtils.getString(userMap, "id");
                userName = MapUtils.getString(userMap, "nickname");

                // 通知相应人员
                message.setRecipient(userId);
                message.setRecipientname(userName);
                message.setCreatetime(new Date());
                messageService.addMessage(message);
            }
        }
    }
}
